{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fcd2d698",
   "metadata": {},
   "source": [
    "# 回顾flask"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b58a36cb",
   "metadata": {},
   "source": [
    "## 本地最初始调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "42198305",
   "metadata": {},
   "outputs": [],
   "source": [
    "from flask import Flask"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "659ae907",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Serving Flask app \"__main__\" (lazy loading)\n",
      " * Environment: production\n",
      "\u001b[31m   WARNING: This is a development server. Do not use it in a production deployment.\u001b[0m\n",
      "\u001b[2m   Use a production WSGI server instead.\u001b[0m\n",
      " * Debug mode: off\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n",
      "127.0.0.1 - - [09/Jul/2022 08:01:07] \"\u001b[37mGET / HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [09/Jul/2022 08:01:07] \"\u001b[33mGET /favicon.ico HTTP/1.1\u001b[0m\" 404 -\n"
     ]
    }
   ],
   "source": [
    "app = Flask(__name__)\n",
    "\n",
    "@app.route('/')\n",
    "def hello_world():\n",
    "    return \"hello world!\"\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2823602c",
   "metadata": {},
   "source": [
    "## 添加新模块render_template"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82deef72",
   "metadata": {},
   "outputs": [],
   "source": [
    "from flask import Flask,render_template\n",
    "app = Flask(__name__)\n",
    "\n",
    "@app.route('/')\n",
    "def hello_world():\n",
    "    return render_template(\n",
    "    \"index.html\")\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59185708",
   "metadata": {},
   "source": [
    "# Bokeh-flask Demo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9419ade",
   "metadata": {},
   "source": [
    "## bokeh demo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cb21db5",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from bokeh import plotting\n",
    "from bokeh.plotting import show,figure,output_notebook\n",
    "output_notebook()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "add48cb6",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#柱状图\n",
    "fig = figure(plot_width=300, plot_height=300)\n",
    "fig.vbar(\n",
    "    x=[1, 2, 3, 4],\n",
    "    width=0.5,\n",
    "    bottom=0,\n",
    "    top=[1.7, 2.2, 4.6, 3.9],\n",
    "    color='navy'\n",
    ")\n",
    "show(fig)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67bfd780",
   "metadata": {},
   "source": [
    "## flask-bokeh初尝试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97ea23e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from flask import Flask,render_template\n",
    "from bokeh.embed import components\n",
    "from bokeh.resources import INLINE\n",
    "from bokeh.plotting import figure\n",
    "\n",
    "app = Flask(__name__)\n",
    "\n",
    "@app.route('/bokeh_demo')\n",
    "def bokeh_demo():\n",
    "    #bokeh绘制柱状图\n",
    "    fig = figure(plot_width=500, plot_height=500)\n",
    "    fig.vbar(\n",
    "        x=[1, 2, 3, 4],\n",
    "        width=0.5,\n",
    "        bottom=0,\n",
    "        top=[1.7, 2.2, 4.6, 3.9],\n",
    "        color='navy'\n",
    "    )\n",
    "    #bokeh中自带的css样式和js要传\n",
    "    #表格转换\n",
    "    js_resources = INLINE.render_js()\n",
    "    css_resources = INLINE.render_css()\n",
    "    script, div = components(fig)\n",
    "    #模板渲染\n",
    "    html = render_template(\n",
    "        'index1.html',\n",
    "        # html文件中的参数=python中处理的参数（名称）\n",
    "        plot_script = script,\n",
    "        plot_div = div,\n",
    "        js_resources = js_resources,\n",
    "        css_resources = css_resources\n",
    "    )\n",
    "    return html\n",
    "    \n",
    "if __name__ == '__main__':\n",
    "    app.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe1420c8",
   "metadata": {},
   "source": [
    "# 课堂_学生实践"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e2b6d90",
   "metadata": {},
   "source": [
    "## bokeh demo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "286cf21a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from bokeh.palettes import Spectral5\n",
    "from bokeh.sampledata.autompg import autompg as df\n",
    "from bokeh.transform import factor_cmap\n",
    "from bokeh.sampledata.autompg import autompg_clean as df\n",
    "df.cyl = df.cyl.astype(str)\n",
    "# df.yr = df.yr.astype(str)\n",
    "group = df.groupby(['cyl', 'mfr']) # 复合条件分组，[缸数、厂家]\n",
    "index_cmap = factor_cmap('cyl_mfr', palette=Spectral5, factors=sorted(df.cyl.unique()), end=1)\n",
    "# 画布\n",
    "p = figure(plot_width=800, plot_height=300, title=\"Mean MPG by # Cylinders and Manufacturer\",\n",
    "           x_range=group, tooltips=[(\"MPG\", \"@mpg_mean\"), (\"Cyl, Mfr\", \"@cyl_mfr\")])\n",
    "# 绘图\n",
    "p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=group,\n",
    "       line_color=\"white\", fill_color=index_cmap, ) # 尾气排放量均值\n",
    "# 其他\n",
    "p.y_range.start = 0\n",
    "p.x_range.range_padding = 0.05  # 同css中的padding\n",
    "p.xgrid.grid_line_color = None\n",
    "p.xaxis.axis_label = \"Manufacturer grouped by # Cylinders\"\n",
    "p.xaxis.major_label_orientation = 1.2 # x轴标签旋转\n",
    "p.outline_line_color = None\n",
    "# 显示\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c867feb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 通过模块-函数调用的方式,将已完成的交互式可视化图进行封装和调用\n",
    "from mpg import MPG\n",
    "show(MPG())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a09e0b76",
   "metadata": {},
   "source": [
    "## flask bokeh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66c81399",
   "metadata": {},
   "outputs": [],
   "source": [
    "from flask import Flask,render_template\n",
    "from bokeh.embed import components\n",
    "from bokeh.resources import INLINE\n",
    "from bokeh.plotting import figure\n",
    "\n",
    "from bokeh.palettes import Spectral5\n",
    "from bokeh.sampledata.autompg import autompg as df\n",
    "from bokeh.transform import factor_cmap\n",
    "from bokeh.sampledata.autompg import autompg_clean as dfb\n",
    "\n",
    "app = Flask(__name__)\n",
    "\n",
    "@app.route('/bokeh_mpg')\n",
    "def bokeh_mpg():\n",
    "    #bokeh绘制Manufacturer grouped by # Cylinders\n",
    "    df.cyl = df.cyl.astype(str)\n",
    "    # df.yr = df.yr.astype(str)\n",
    "    group = df.groupby(['cyl', 'mfr']) # 复合条件分组，[缸数、厂家]\n",
    "    index_cmap = factor_cmap('cyl_mfr', palette=Spectral5, factors=sorted(df.cyl.unique()), end=1)\n",
    "    # 画布\n",
    "    p = figure(plot_width=800, plot_height=300, title=\"Mean MPG by # Cylinders and Manufacturer\",\n",
    "    x_range=group, tooltips=[(\"MPG\", \"@mpg_mean\"), (\"Cyl, Mfr\", \"@cyl_mfr\")])\n",
    "    # 绘图\n",
    "    p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=group,\n",
    "    line_color=\"white\", fill_color=index_cmap, ) # 尾气排放量均值\n",
    "    # 其他\n",
    "    p.y_range.start = 0\n",
    "    p.x_range.range_padding = 0.05  # 同css中的padding\n",
    "    p.xgrid.grid_line_color = None\n",
    "    p.xaxis.axis_label = \"Manufacturer grouped by # Cylinders\"\n",
    "    p.xaxis.major_label_orientation = 1.2 # x轴标签旋转\n",
    "    p.outline_line_color = None\n",
    "    \n",
    "    #bokeh中自带的css样式和js要传\n",
    "    #表格转换\n",
    "    js_resources = INLINE.render_js()\n",
    "    css_resources = INLINE.render_css()\n",
    "    script, div = components(p)\n",
    "    #模板渲染\n",
    "    html = render_template(\n",
    "        'index1.html',\n",
    "        # html文件中的参数=python中处理的参数（名称）\n",
    "        plot_script = script,\n",
    "        plot_div = div,\n",
    "        js_resources = js_resources,\n",
    "        css_resources = css_resources\n",
    "    )\n",
    "    return html\n",
    "    \n",
    "if __name__=='__main__':\n",
    "    server = make_server(('127.0.0.1', 5000), app)\n",
    "    server.serve_forever()\n",
    "    app.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1e422a92",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
